package com.uniview.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;



/**
 * 
 * DES加解密工具类
 * 
 */
public class DESUtil {

	private static final String Algorithm = "DESede"; // 加密算法(DES,DESede,Blowfish)

	private static final String DefaultKey = "SDMS#2019@Uni"; // 默认加密key

	/**
	 * 3DES解密
	 * 
	 * @param pwd
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String pwd) throws Exception {
		return decrypt(pwd, DefaultKey);
	}

	/**
	 * 3DES加密
	 * 
	 * @param plain
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(String plain) throws Exception {
		return encrypt(plain, DefaultKey);
	}

	/**
	 * 3DES解密
	 * 
	 * @param value
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String value, String key) throws Exception {
		return new String(decryptMode(GetKeyBytes(key), Base64.decode(value,Base64.DEFAULT)));
	}

	/**
	 * 3DES加密
	 * 
	 * @param value
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(String value, String key) throws Exception {
		return byte2Base64(encryptMode(GetKeyBytes(key), value.getBytes("UTF-8")));
	}

	/**
	 * 计算24位长的密码byte值,首先对原始密钥做MD5算hash值，再用前8位数据对应补全后8位
	 * 
	 * @param strKey
	 * @return
	 * @throws Exception
	 */
	private static byte[] GetKeyBytes(String strKey) throws Exception {
		if (null == strKey || strKey.length() < 1)
			throw new Exception("key is null or empty!");
		java.security.MessageDigest alg = java.security.MessageDigest
				.getInstance("MD5");
		alg.update(strKey.getBytes());
		byte[] bkey = alg.digest();
		int start = bkey.length;
		byte[] bkey24 = new byte[24];
		for (int i = 0; i < start; i++) {
			bkey24[i] = bkey[i];
		}

		for (int i = start; i < 24; i++) {// 为了与.net16位key兼容
			bkey24[i] = bkey[i - start];
		}
		return bkey24;
	}

	/**
	 * 
	 * @param keybyte
	 *            keybyte为加密密钥，长度为24字节
	 * @param src
	 *            src为被加密的数据缓冲区（源）
	 * @return
	 */
	private static byte[] encryptMode(byte[] keybyte, byte[] src)
			throws Exception {
		// 生成密钥
		SecretKey deskey = new SecretKeySpec(keybyte, Algorithm); // 加密
		Cipher c1 = Cipher.getInstance(Algorithm);
		c1.init(Cipher.ENCRYPT_MODE, deskey);
		return c1.doFinal(src);
	}

	/**
	 * 
	 * @param keybyte
	 *            为加密密钥，长度为24字节
	 * @param src
	 *            为加密后的缓冲区
	 * @return
	 * @throws Exception
	 */
	private static byte[] decryptMode(byte[] keybyte, byte[] src)
			throws Exception {
		// 生成密钥
		SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
		// 解密
		Cipher c1 = Cipher.getInstance(Algorithm);
		c1.init(Cipher.DECRYPT_MODE, deskey);
		return c1.doFinal(src);
	}

	/**
	 * 转换成base64编码
	 * 
	 * @param b
	 * @return
	 */
	private static String byte2Base64(byte[] b) {
		return new String(Base64.encode(b,Base64.DEFAULT));
	}

	public static void main(String[] args) {
		//String plain = "password";
		try {
			String pwd = DESUtil.encrypt("SDMS2019@Uniview");
			System.out.println(pwd);
//			System.out.println(DESUtil.decrypt("dMy9FvWh6OHfDSh8qqNtXg=="));
		} catch (Exception er) {
			er.printStackTrace();
		}
	}

}
